package com.ssy.lingxi.member.merchant.serviceimpl.base;

import com.ssy.lingxi.common.constant.manage.ShopTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberLevelTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberStatusEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.constant.MemberRelationTypeEnum;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.bo.LevelBO;
import com.ssy.lingxi.member.merchant.model.bo.ProcessBO;
import com.ssy.lingxi.member.merchant.model.constant.*;
import com.ssy.lingxi.member.merchant.model.dto.CommentSummaryDTO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.MemberTypeIdVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.RoleIdVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.*;
import com.ssy.lingxi.member.merchant.model.vo.info.request.MemberInfoAddRoleVO;
import com.ssy.lingxi.member.merchant.model.vo.info.request.MemberInfoUpdateDepositDetailVO;
import com.ssy.lingxi.member.merchant.model.vo.info.request.MemberInfoUpdateRegisterDetailVO;
import com.ssy.lingxi.member.merchant.model.vo.info.response.*;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.response.MemberAppraisalPageQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.response.MemberCreditComplaintPageQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.lifecycle.response.MemberRecordRectifyVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.request.MemberDetailCreditHistoryPageVO;
import com.ssy.lingxi.member.merchant.model.vo.maintenance.response.*;
import com.ssy.lingxi.member.merchant.model.vo.mobile.request.MobileUpdateDepositDetailVO;
import com.ssy.lingxi.member.merchant.model.vo.mobile.response.MobileInfoApplyButtonVO;
import com.ssy.lingxi.member.merchant.model.vo.mobile.response.MobileUpdateDepositDetailQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.platform.response.MemberManageVO;
import com.ssy.lingxi.member.merchant.model.vo.platform.response.RoleRuleManageVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.ValidateIdPageVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.response.MemberValidateDetailLevelVO;
import com.ssy.lingxi.member.merchant.model.vo.validate.response.WorkFlowStepVO;
import com.ssy.lingxi.member.merchant.repository.*;
import com.ssy.lingxi.member.merchant.service.base.*;
import com.ssy.lingxi.member.merchant.service.web.IMemberAppraisalService;
import com.ssy.lingxi.member.merchant.service.web.IMemberComplaintService;
import com.ssy.lingxi.member.merchant.service.web.IMemberRectifyService;
import com.ssy.lingxi.member.merchant.utils.AgentAreaUtil;
import com.ssy.lingxi.member.merchant.utils.NumberUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 会员信息管理查询服务接口
 * @author 万宁
 * @version 2.0.0
 * @date 2020-09-05
 */
@Service
public class BaseMemberInfoServiceImpl implements IBaseMemberInfoService {
    @Resource
    private MemberRepository memberRepository;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private MemberTypeRepository memberTypeRepository;

    @Resource
    private IBaseMemberDetailService baseMemberDetailService;

    @Resource
    private IBaseMemberLevelConfigService baseMemberLevelConfigService;

    @Resource
    private IBaseMemberRegisterDetailService baseMemberRegisterDetailService;

    @Resource
    private IBaseMemberDepositDetailService baseMemberDepositDetailService;

    @Resource
    private IBaseMemberHistoryService baseMemberHistoryService;

    @Resource
    private IBasePlatformProcessService basePlatformProcessService;

    @Resource
    private MemberTradeCommentHistoryRepository memberTradeCommentHistoryRepository;

    @Resource
    private MemberAfterSaleHistoryRepository memberAfterSaleHistoryRepository;

    @Resource
    private IBaseMemberValidateService baseMemberValidateService;

    @Resource
    private RoleRepository roleRepository;

    @Resource
    private IBaseMemberInnerService memberInnerService;

    @Resource
    private IBaseMemberQualificationService baseMemberQualificationService;

    @Resource
    private IMemberAppraisalService memberAppraisalService;

    @Resource
    private IMemberRectifyService memberRectifyService;

    @Resource
    private IMemberComplaintService memberComplaintService;

    @Resource
    private RoleRuleRepository roleRuleRepository;

    /**
     * 获取分页查询页面下拉框内容
     * @return 下拉框内容
     */
    @Override
    public Wrapper<MemberInfoSearchConditionVO> getPageSearchConditions() {
        MemberInfoSearchConditionVO conditionVO = new MemberInfoSearchConditionVO();
        List<DropdownItem> itemList = MemberOuterStatusEnum.toDropdownList();
        itemList.add(0, new DropdownItem(0, MemberStringEnum.CHOOSE.getName()));
        conditionVO.setOuterStatus(itemList);
        return Wrapper.success(conditionVO);
    }

    /**
     * 分页、模糊查询归属会员列表（带积分权益）
     *
     * @param subMemberId 下级会员Id
     * @param subRoleId   下级会员角色Id
     * @param current     当前页
     * @param pageSize    每页行数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MobileInfoLevelRightQueryVO>> pageUpperMemberLevelRights(Long subMemberId, Long subRoleId, int current, int pageSize) {
        Pageable pageable = PageRequest.of(current - 1, pageSize, Sort.by("id").ascending());
        Page<MemberRelationDO> pageList = relationRepository.findBySubMemberIdAndSubRoleId(subMemberId, subRoleId, pageable);

        //注意！！！这里返回的是下级会员的memberId，所以都是一样的
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(relationDO -> {
            MobileInfoLevelRightQueryVO infoVO = new MobileInfoLevelRightQueryVO();
            infoVO.setValidateId(relationDO.getId());
            infoVO.setUpperMemberId(relationDO.getMemberId());
            infoVO.setUpperRoleId(relationDO.getRoleId());
            infoVO.setLogo(relationDO.getMember().getLogo());
            infoVO.setUpperMemberName(relationDO.getMember().getName());
            infoVO.setLevel(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getLevel());
            infoVO.setLevelTag(relationDO.getLevelRight() == null ? "" : relationDO.getLevelRight().getLevelTag());
            infoVO.setScore(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getScore());
            LevelBO levelBO = baseMemberLevelConfigService.findNextLevel(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubRoleId(), relationDO.getLevelRight().getLevel());
            infoVO.setNextLevelTag(levelBO.getNextTag());
            infoVO.setNextScore(levelBO.getNextScore());
            infoVO.setSumReturnMoney(relationDO.getLevelRight() == null ? BigDecimal.ZERO : relationDO.getLevelRight().getSumReturnMoney());
            infoVO.setCurrentPoint(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getCurrentPoint());
            infoVO.setStatus(relationDO.getStatus());
            infoVO.setStatusName(MemberStatusEnum.getCodeMessage(infoVO.getStatus()));

            return infoVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 分页、模糊查询归属会员列表
     * @param subMemberId 下级会员Id
     * @param subRoleId   下级会员角色Id
     * @param name 上级会员名称
     * @param startDate 申请起始日期，格式为yyyy-MM-dd
     * @param endDate   申请结束日期，格式为yyyy-MM-dd
     * @param outerStatus 审核状态（外部）
     * @param current 当前页（从1开始）
     * @param pageSize 每页行数
     * @param enableMultiTenancy 是否开启SAAS多租户部署
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<UpperMemberInfoVO>> pageUpperMembers(Long subMemberId, Long subRoleId, String name, String startDate, String endDate, Integer outerStatus, int current, int pageSize, Boolean enableMultiTenancy) {
        MemberDO subMemberDO = memberRepository.findById(subMemberId).orElse(null);
        if (subMemberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("subMemberId").as(Long.class), subMemberId));

            if(NumberUtil.notNullOrZero(subRoleId)) {
                list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), subRoleId));
            }

            if (StringUtils.hasLength(startDate)) {
                LocalDateTime startDateTime = LocalDateTime.parse(startDate.concat(" 00:00:00"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), startDateTime));
            }

            if (StringUtils.hasLength(endDate)) {
                LocalDateTime endDateTime = LocalDateTime.parse(endDate.concat(" 23:59:59"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), endDateTime));
            }

            if (NumberUtil.notNullOrZero(outerStatus)) {
                list.add(criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), outerStatus));
            }

            //会员名称
            if (StringUtils.hasLength(name)) {
                Join<Object, Object> memberJoin = root.join("member", JoinType.LEFT);
                list.add(criteriaBuilder.like(memberJoin.get("name").as(String.class), "%" + name.trim() + "%"));
            }

            //如果开启SAAS多租户部署 就隐藏 会员等级类型 为 平台会员 的会员数据
            if(enableMultiTenancy){
                list.add(criteriaBuilder.notEqual(root.get("subMemberLevelTypeEnum").as(Integer.class), MemberLevelTypeEnum.PLATFORM.getCode()));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Pageable page = PageRequest.of(current - 1, pageSize, Sort.by("id").ascending());
        Page<MemberRelationDO> pageList = relationRepository.findAll(specification, page);

        //注意！！！这里返回的是下级会员的memberId，所以都是一样的
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(relationDO -> {
            UpperMemberInfoVO infoVO = new UpperMemberInfoVO();
            infoVO.setMemberId(relationDO.getSubMemberId());
            infoVO.setValidateId(relationDO.getId());
            infoVO.setName(relationDO.getMember().getName());
            infoVO.setLogo(StringUtils.hasLength(relationDO.getMember().getLogo()) ? relationDO.getMember().getLogo() : "");
            infoVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            infoVO.setRoleName(relationDO.getSubRole().getRoleName());
            infoVO.setLevelTypeEnum(relationDO.getSubMemberLevelTypeEnum());
            infoVO.setLevelTypeName(MemberLevelTypeEnum.getCodeMsg(relationDO.getSubMemberLevelTypeEnum()));
            infoVO.setLevel(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getLevel());
            infoVO.setLevelTag(relationDO.getLevelRight() == null ? "" : relationDO.getLevelRight().getLevelTag());
            infoVO.setRegisterTime(relationDO.getCreateTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));
            infoVO.setDepositTime(relationDO.getDepositTime() == null ? "" : relationDO.getDepositTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));
            infoVO.setStatus(relationDO.getStatus());
            infoVO.setStatusName(MemberStatusEnum.getCodeMessage(infoVO.getStatus()));
            infoVO.setOuterStatus(relationDO.getOuterStatus());
            infoVO.setOuterStatusName(MemberOuterStatusEnum.getCodeMsg(infoVO.getOuterStatus()));

            infoVO.setShowUpdate(false);
            infoVO.setShowModify(false);
            if(relationDO.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
                //平台审核通过或不通过，显示“修改”，不显示“变更”
                if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode()) || relationDO.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED.getCode())) {
                    infoVO.setShowUpdate(true);
                    infoVO.setShowModify(false);
                } else {
                    if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITORY_NOT_PASSED.getCode())) {
                        infoVO.setShowUpdate(true);
                        infoVO.setShowModify(false);
                    } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode()) || relationDO.getOuterStatus().equals(MemberOuterStatusEnum.MODIFY_PASSED.getCode()) || relationDO.getOuterStatus().equals(MemberOuterStatusEnum.MODIFY_NOT_PASSED.getCode())){
                        infoVO.setShowUpdate(false);
                        infoVO.setShowModify(true);
                    }
                }
            }

            return infoVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “申请会员”页面，查询申请按钮状态和文本
     *
     * @param loginUser     登录用户
     * @param shopType       商城类型
     * @param upperMemberId 上级会员Id
     * @param upperRoleId   上级角色Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoApplyButtonVO> getApplyCondition(UserLoginCacheDTO loginUser, Integer shopType, Long upperMemberId, Long upperRoleId) {
        if(loginUser.getMemberId().equals(upperMemberId)) {
            return Wrapper.success(new MemberInfoApplyButtonVO(MemberApplyButtonStatusEnum.DO_NOT_SHOW, ShopTypeEnum.parseCode(shopType), 0L));
        }

        MemberRelationDO upperRelation = relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelType(upperMemberId, upperRoleId, MemberRelationTypeEnum.PLATFORM.getCode());
        Long validateId = 0L;
        MemberApplyButtonStatusEnum statusEnum = MemberApplyButtonStatusEnum.CAN_NOT_APPLY;

        // 上级会员平台审核没有通过，不能申请
        if(upperRelation == null || upperRelation.getVerified().equals(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode()) || !upperRelation.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
            return Wrapper.success(new MemberInfoApplyButtonVO(statusEnum, ShopTypeEnum.parseCode(shopType), validateId));
        }

        // 等级类型不一致，不能申请
        Integer upperMemberLevelType = MemberLevelTypeEnum.getCodeByMemberType(upperRelation.getSubRole().getMemberType().getTypeEnum());
        if(!loginUser.getMemberLevelType().equals(upperMemberLevelType)) {
            return Wrapper.success(new MemberInfoApplyButtonVO(statusEnum, ShopTypeEnum.parseCode(shopType), validateId));
        }

        MemberRelationDO relationDO = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(upperMemberId, upperRoleId, loginUser.getMemberId(), loginUser.getMemberRoleId());
        if(relationDO == null) {
            if(shopType.equals(ShopTypeEnum.PURCHASE.getCode())) {
                //如果是采购门户，需要判断申请的会员是否商户会员且为服务提供者
                if(loginUser.getMemberLevelType().equals(MemberLevelTypeEnum.MERCHANT.getCode()) && loginUser.getMemberRoleType().equals(RoleTypeEnum.SERVICE_PROVIDER.getCode())) {
                    statusEnum = MemberApplyButtonStatusEnum.PROCEED;
                } else {
                    statusEnum = MemberApplyButtonStatusEnum.CAN_NOT_APPLY;
                }
            } else {
                statusEnum = MemberApplyButtonStatusEnum.PROCEED;
            }
        } else {
            if(relationDO.getStatus().equals(MemberStatusEnum.BLACK_LIST.getCode())) {
                statusEnum = MemberApplyButtonStatusEnum.BLACKLIST;
            } else if(relationDO.getStatus().equals(MemberStatusEnum.ELIMINATED.getCode())) {
                statusEnum = MemberApplyButtonStatusEnum.ELIMINATED;
            } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITING.getCode())){
                validateId = relationDO.getId();
                statusEnum = MemberApplyButtonStatusEnum.DEPOSITING;
            } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode())) {
                validateId = relationDO.getId();
                statusEnum = MemberApplyButtonStatusEnum.DEPOSIT_PASSED;
            } else {
                statusEnum = MemberApplyButtonStatusEnum.CAN_NOT_APPLY;
            }
        }

        return Wrapper.success(new MemberInfoApplyButtonVO(statusEnum, ShopTypeEnum.parseCode(shopType), validateId));
    }

    /**
     * App - “申请会员”页面，查询申请按钮状态和文本
     *
     * @param loginUser     登录用户
     * @param upperMemberId 上级会员Id
     * @param upperRoleId   上级角色Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MobileInfoApplyButtonVO> getMobileApplyCondition(UserLoginCacheDTO loginUser, Long upperMemberId, Long upperRoleId) {
        if(loginUser.getMemberId().equals(upperMemberId)) {
            return Wrapper.success(new MobileInfoApplyButtonVO(MobileApplyButtonStatusEnum.CAN_NOT_BE_SELF_SUB_MEMBER));
        }

        MemberRelationDO upperRelation = relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelType(upperMemberId, upperRoleId, MemberRelationTypeEnum.PLATFORM.getCode());
        MobileApplyButtonStatusEnum statusEnum = MobileApplyButtonStatusEnum.DO_NOT_SHOW;

        // 上级会员平台审核没有通过，不能申请
        if(upperRelation == null || upperRelation.getVerified().equals(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode()) || !upperRelation.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
            return Wrapper.success(new MobileInfoApplyButtonVO(statusEnum));
        }

        // 等级类型不一致，不能申请
        Integer upperMemberLevelType = MemberLevelTypeEnum.getCodeByMemberType(upperRelation.getSubRole().getMemberType().getTypeEnum());
        if(!loginUser.getMemberLevelType().equals(upperMemberLevelType)) {
            return Wrapper.success(new MobileInfoApplyButtonVO(statusEnum));
        }

        String validateMsg = "";
        MemberRelationDO relationDO = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(upperMemberId, upperRoleId, loginUser.getMemberId(), loginUser.getMemberRoleId());
        if(relationDO == null) {
            statusEnum = MobileApplyButtonStatusEnum.PROCEED;
        } else {
            if(relationDO.getStatus().equals(MemberStatusEnum.BLACK_LIST.getCode())) {
                statusEnum = MobileApplyButtonStatusEnum.BLACKLIST;
            } else if(relationDO.getStatus().equals(MemberStatusEnum.ELIMINATED.getCode())) {
                statusEnum = MobileApplyButtonStatusEnum.ELIMINATED;
            } else if(relationDO.getStatus().equals(MemberStatusEnum.FROZEN.getCode())) {
                statusEnum = MobileApplyButtonStatusEnum.FROZEN;
            } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITING.getCode())){
                statusEnum = MobileApplyButtonStatusEnum.DEPOSITING;
            } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode())) {
                statusEnum = MobileApplyButtonStatusEnum.DEPOSIT_PASSED;
            } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITORY_NOT_PASSED.getCode())) {
                validateMsg = relationDO.getValidateMsg();
                statusEnum = MobileApplyButtonStatusEnum.DEPOSIT_NOT_PASS;
            } else {
                statusEnum = MobileApplyButtonStatusEnum.DO_NOT_SHOW;
            }
        }

        return Wrapper.success(new MobileInfoApplyButtonVO(statusEnum, validateMsg));
    }

    /**
     * “邀请会员”页面，查询邀请按钮状态和文本
     *
     * @param loginUser     登录用户
     * @param shopType      商城类型
     * @param subMemberId 下级会员Id
     * @param subRoleId   下级角色Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoInviteButtonVO> getInviteCondition(UserLoginCacheDTO loginUser, Integer shopType, Long subMemberId, Long subRoleId) {
        if(loginUser.getMemberId().equals(subMemberId)) {
            return Wrapper.success(new MemberInfoInviteButtonVO(MemberInviteButtonStatusEnum.DO_NOT_SHOW, 0L));
        }

        MemberRelationDO subRelation = relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelType(subMemberId, subRoleId, MemberRelationTypeEnum.PLATFORM.getCode());
        Long validateId = 0L;
        MemberInviteButtonStatusEnum statusEnum = MemberInviteButtonStatusEnum.CAN_NOT_INVITE;

        // 下级会员平台审核没有通过，不能邀请
        if(subRelation == null || subRelation.getVerified().equals(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode()) || !subRelation.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
            return Wrapper.success(new MemberInfoInviteButtonVO(statusEnum, validateId));
        }

        // 等级类型不一致，不能申请
        Integer subMemberLevelType = MemberLevelTypeEnum.getCodeByMemberType(subRelation.getSubRole().getMemberType().getTypeEnum());
        if(!loginUser.getMemberLevelType().equals(subMemberLevelType)) {
            return Wrapper.success(new MemberInfoInviteButtonVO(statusEnum, validateId));
        }

        MemberRelationDO relationDO = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(loginUser.getMemberId(), loginUser.getMemberRoleId(), subMemberId, subRoleId);
        if(relationDO == null) {
            statusEnum = MemberInviteButtonStatusEnum.PROCEED;
        } else {
            if(relationDO.getStatus().equals(MemberStatusEnum.BLACK_LIST.getCode())) {
                statusEnum = MemberInviteButtonStatusEnum.BLACKLIST;
            } else if(relationDO.getStatus().equals(MemberStatusEnum.ELIMINATED.getCode())) {
                statusEnum = MemberInviteButtonStatusEnum.ELIMINATED;
            } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITING.getCode())){
                validateId = subRelation.getId();
                statusEnum = MemberInviteButtonStatusEnum.DEPOSITING;
            } else if(relationDO.getOuterStatus().equals(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode())) {
                validateId = subRelation.getId();
                statusEnum = MemberInviteButtonStatusEnum.DEPOSIT_PASSED;
            } else {
                statusEnum = MemberInviteButtonStatusEnum.CAN_NOT_INVITE;
            }
        }

        return Wrapper.success(new MemberInfoInviteButtonVO(statusEnum, validateId));
    }

    /**
     * “申请会员”页面，会员注册资料信息
     *
     * @param loginUser     登录用户
     * @param upperMemberId 上级会员Id
     * @param upperRoleId   上级会员角色Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoApplyRegisterDetailVO> getApplyRegisterDetail(UserLoginCacheDTO loginUser, Long upperMemberId, Long upperRoleId) {
        MemberDO member = memberRepository.findById(loginUser.getMemberId()).orElse(null);
        if(member == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        RoleDO upperRole = roleRepository.findById(upperRoleId).orElse(null);
        if(upperRole == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        MemberInfoApplyRegisterDetailVO detailVO = new MemberInfoApplyRegisterDetailVO();
        detailVO.setProcessName(MemberStringEnum.MEMBER_DEPOSIT_OUTER_PROCESS.getName());
        detailVO.setOuterVerifySteps(baseMemberValidateService.getMemberDepositOuterSteps(upperRole.getRoleName(), loginUser.getMemberRoleName()));
        detailVO.setCurrentOuterStep(1);
        detailVO.setRegisterDetails(baseMemberRegisterDetailService.groupMemberRegisterDetailText(member));

        return Wrapper.success(detailVO);
    }

    /**
     * “申请会员”页面，会员入库资料信息
     *
     * @param loginUser     登录用户
     * @param upperMemberId 上级会员Id
     * @param upperRoleId   上级会员角色Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoApplyDepositDetailVO> getApplyDepositDetail(UserLoginCacheDTO loginUser, Long upperMemberId, Long upperRoleId) {
        MemberDO member = memberRepository.findById(loginUser.getMemberId()).orElse(null);
        if(member == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        RoleDO upperRole = roleRepository.findById(upperRoleId).orElse(null);
        if(upperRole == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        RoleDO roleDO = roleRepository.findById(loginUser.getMemberRoleId()).orElse(null);
        if(roleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        MemberInfoApplyDepositDetailVO detailVO = new MemberInfoApplyDepositDetailVO();
        detailVO.setProcessName(MemberStringEnum.MEMBER_CHANGE_OUTER_PROCESS.getName());
        detailVO.setOuterVerifySteps(Stream.of(new WorkFlowStepVO(1, MemberStringEnum.MEMBER_CHANGE_OUTER_STEP_ONE.getName(), roleDO.getRoleName()), new WorkFlowStepVO(2, MemberStringEnum.MEMBER_CHANGE_OUTER_STEP_TWO.getName(), upperRole.getRoleName())).collect(Collectors.toList()));
        detailVO.setCurrentOuterStep(1);
        detailVO.setDepositDetails(baseMemberDepositDetailService.groupMemberConfig(baseMemberDepositDetailService.findMemberDepositoryConfig(upperMemberId, upperRoleId, roleDO)));
        return Wrapper.success(detailVO);
    }

    /**
     * 获取“修改会员信息”页面，会员注册资料信息
     * @param loginUser 登录用户
     * @param validateId 会员关系Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoUpdateDetailVO> getMemberRegisterDetail(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //平台会员才可以修改资料后重新提交审核
        if (!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.PLATFORM.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_NEED_PLATFORM_LEVEL_TYPE);
        }

        //审核通过或不通过，才能修改信息
        if (!relationDO.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode()) && !relationDO.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VERIFYING);
        }

        MemberInfoUpdateDetailVO detailVO = new MemberInfoUpdateDetailVO();
        detailVO.setProcessName(MemberStringEnum.MEMBER_VALIDATE_PROCESS.getName());
        //审核流程
        detailVO.setOuterVerifySteps(baseMemberValidateService.getPlatformValidateOuterSteps(relationDO.getSubRoleName()));
        //外部审核步骤
        detailVO.setCurrentOuterStep(1);

        //基本信息
        detailVO.setMemberId(relationDO.getSubMemberId());
        detailVO.setValidateId(relationDO.getId());

        //详细信息分组内容
        detailVO.setGroups(baseMemberRegisterDetailService.groupMemberRegisterDetail(relationDO.getSubMember(), MemberDetailVersionEnum.USING));

        //外部历史记录（即历史流转记录）
        detailVO.setOuterHistory(baseMemberHistoryService.listMemberOuterHistory(relationDO));

        return Wrapper.success(detailVO);
    }

    /**
     * App - 获取“修改会员信息”页面，会员注册资料信息
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MobileInfoUpdateDetailVO> getMobileMemberRegisterDetail(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //会员等级类型为平台会员的审核不通过状态可以修改资料后重新提交审核
        if (!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.PLATFORM.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_NEED_PLATFORM_LEVEL_TYPE);
        }

        MobileInfoUpdateDetailVO detailVO = new MobileInfoUpdateDetailVO();
        detailVO.setStatus(relationDO.getOuterStatus());
        detailVO.setValidateMsg(StringUtils.hasLength(relationDO.getValidateMsg()) ? relationDO.getValidateMsg() : "");

        //详细信息分组内容
        detailVO.setGroups(baseMemberRegisterDetailService.groupMemberRegisterDetail(relationDO.getSubMember(), MemberDetailVersionEnum.USING));
        return Wrapper.success(detailVO);
    }

    /**
     * 平台会员，修改会员信息
     * @param loginUser 登录用户
     * @param detailVO 接口参数
     * @return 修改结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateMemberRegisterDetail(UserLoginCacheDTO loginUser, MemberInfoUpdateRegisterDetailVO detailVO) {
        //修改注册信息后，强制重新提交平台审核
        //由于注册信息是所有角色共用的，所以要判断所有角色的平台会员
        List<MemberRelationDO> relationList = relationRepository.findBySubMemberIdAndRelType(loginUser.getMemberId(), MemberRelationTypeEnum.PLATFORM.getCode());
        if(CollectionUtils.isEmpty(relationList)) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MemberRelationDO relationDO = relationList.stream().filter(relation -> relation.getId().equals(detailVO.getValidateId())).findFirst().orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //审核进行中（状态不为“通过”、“未通过”），不能修改信息
        MemberRelationDO otherRoleRelation = relationList.stream().filter(relation -> !relation.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode()) && !relation.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED.getCode())).findFirst().orElse(null);
        if(otherRoleRelation != null) {
            return Wrapper.fail(otherRoleRelation.getId().equals(relationDO.getId()) ? ResponseCode.MC_MS_MEMBER_VERIFYING : ResponseCode.MC_MS_MEMBER_HAS_ANOTHER_ROLE_IS_VERIFYING);
        }

        return baseMemberRegisterDetailService.updatePlatformMemberRegisterDetail(relationDO, "", detailVO.getDetail(), false,true);
    }

    /**
     * 获取“修改会员信息”页面，会员入库资料信息
     *
     * @param loginUser  登录用户
     * @param validateId 会员关系Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoUpdateDepositDetailQueryVO> getMemberDepositDetail(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //非平台会员才可以修改入库资料
        if (!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.MERCHANT.getCode()) && !relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.CHANNEL.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_NEED_MERCHANT_OR_CHANNEL_LEVEL_TYPE);
        }

        List<Integer> outerStatusList = Stream.of(MemberOuterStatusEnum.DEPOSITORY_PASSED, MemberOuterStatusEnum.DEPOSITORY_NOT_PASSED, MemberOuterStatusEnum.MODIFY_PASSED, MemberOuterStatusEnum.MODIFY_NOT_PASSED).map(MemberOuterStatusEnum::getCode).collect(Collectors.toList());
        if(!outerStatusList.contains(relationDO.getOuterStatus())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VERIFYING);
        }

        MemberInfoUpdateDepositDetailQueryVO detailVO = new MemberInfoUpdateDepositDetailQueryVO();
        detailVO.setProcessName(MemberStringEnum.MEMBER_CHANGE_PROCESS.getName());
        //审核流程
        detailVO.setOuterVerifySteps(baseMemberValidateService.getMemberModifyOuterSteps(relationDO));
        //外部审核步骤
        detailVO.setCurrentOuterStep(1);

        //基本信息
        detailVO.setMemberId(relationDO.getSubMemberId());
        detailVO.setValidateId(relationDO.getId());

        //详细信息分组内容
        detailVO.setGroups(baseMemberDepositDetailService.switchMemberDepositoryDetail(relationDO));

        //资质证明文件
        detailVO.setQualities(baseMemberQualificationService.findMemberQualities(relationDO));

        //外部历史记录（即历史流转记录）
        detailVO.setOuterHistory(baseMemberHistoryService.listMemberOuterHistory(relationDO));

        return Wrapper.success(detailVO);
    }

    /**
     * App - 获取“修改会员信息”页面，会员入库资料信息
     *
     * @param loginUser     登录用户
     * @param upperMemberId 上级会员Id
     * @param upperRoleId   上级会员角色Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MobileUpdateDepositDetailQueryVO> getMemberDepositDetail(UserLoginCacheDTO loginUser, Long upperMemberId, Long upperRoleId) {
        MemberRelationDO relationDO = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(upperMemberId, upperRoleId, loginUser.getMemberId(), loginUser.getMemberRoleId());
        if (relationDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //非平台会员才可以修改入库资料
        if (!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.MERCHANT.getCode()) && !relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.CHANNEL.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_NEED_MERCHANT_OR_CHANNEL_LEVEL_TYPE);
        }

        List<Integer> outerStatusList = Stream.of(MemberOuterStatusEnum.DEPOSITORY_PASSED, MemberOuterStatusEnum.DEPOSITORY_NOT_PASSED, MemberOuterStatusEnum.MODIFY_PASSED, MemberOuterStatusEnum.MODIFY_NOT_PASSED).map(MemberOuterStatusEnum::getCode).collect(Collectors.toList());
        if(!outerStatusList.contains(relationDO.getOuterStatus())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VERIFYING);
        }

        MobileUpdateDepositDetailQueryVO detailVO = new MobileUpdateDepositDetailQueryVO();
        //详细信息分组内容
        detailVO.setGroups(baseMemberDepositDetailService.switchMemberDepositoryDetail(relationDO));

        //资质证明文件
        detailVO.setQualities(baseMemberQualificationService.findMemberQualities(relationDO));
        return Wrapper.success(detailVO);
    }

    /**
     * App - 修改会员入库信息
     *
     * @param loginUser 登录用户
     * @param detailVO  接口参数
     * @return 修改结果
     */
    @Override
    public Wrapper<Void> updateMobileDepositDetail(UserLoginCacheDTO loginUser, MobileUpdateDepositDetailVO detailVO) {
        MemberRelationDO relationDO = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(detailVO.getUpperMemberId(), detailVO.getUpperRoleId(), loginUser.getMemberId(), loginUser.getMemberRoleId());
        if (relationDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //非平台会员才可以修改入库资料.
        if (!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.MERCHANT.getCode()) && !relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.CHANNEL.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_NEED_MERCHANT_OR_CHANNEL_LEVEL_TYPE);
        }

        List<Integer> outerStatusList = Stream.of(MemberOuterStatusEnum.DEPOSITORY_PASSED, MemberOuterStatusEnum.DEPOSITORY_NOT_PASSED, MemberOuterStatusEnum.MODIFY_PASSED, MemberOuterStatusEnum.MODIFY_NOT_PASSED).map(MemberOuterStatusEnum::getCode).collect(Collectors.toList());
        if(!outerStatusList.contains(relationDO.getOuterStatus())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VERIFYING);
        }

        //先保存资质文件
        Wrapper<Void> result = baseMemberQualificationService.checkAndSaveMemberQualities(relationDO, detailVO.getQualities());
        if(result.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(result.getCode(), result.getMessage());
        }

        return baseMemberDepositDetailService.checkAndUpdateMemberDepositoryDetail(relationDO, detailVO.getDepositDetails());
    }

    /**
     * 修改会员入库信息
     *
     * @param loginUser 登录用户
     * @param detailVO  接口参数
     * @return 修改结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateMemberDepositDetail(UserLoginCacheDTO loginUser, MemberInfoUpdateDepositDetailVO detailVO) {
        MemberRelationDO relationDO = relationRepository.findById(detailVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //非平台会员才可以修改入库资料.
        if (!relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.MERCHANT.getCode()) && !relationDO.getSubMemberLevelTypeEnum().equals(MemberLevelTypeEnum.CHANNEL.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_NEED_MERCHANT_OR_CHANNEL_LEVEL_TYPE);
        }

        List<Integer> outerStatusList = Stream.of(MemberOuterStatusEnum.DEPOSITORY_PASSED, MemberOuterStatusEnum.DEPOSITORY_NOT_PASSED, MemberOuterStatusEnum.MODIFY_PASSED, MemberOuterStatusEnum.MODIFY_NOT_PASSED).map(MemberOuterStatusEnum::getCode).collect(Collectors.toList());
        if(!outerStatusList.contains(relationDO.getOuterStatus())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VERIFYING);
        }

        //先保存资质文件
        Wrapper<Void> result = baseMemberQualificationService.checkAndSaveMemberQualities(relationDO, detailVO.getQualities());
        if(result.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(result.getCode(), result.getMessage());
        }

        return baseMemberDepositDetailService.checkAndUpdateMemberDepositoryDetail(relationDO, detailVO.getDetail());
    }

    /**
     * 会员详情 - 会员基本信息
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoBasicDetailVO> getMemberBasicDetail(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        SubMemberDetailVO subMemberDetailVO = baseMemberDetailService.getSubMemberDetail(relationDO);

        MemberInfoBasicDetailVO detailVO = new MemberInfoBasicDetailVO();
        BeanUtils.copyProperties(subMemberDetailVO, detailVO);

        if(relationDO.getRelType().equals(MemberRelationTypeEnum.PLATFORM.getCode())) {
            detailVO.setProcessName(MemberStringEnum.MEMBER_VALIDATE_PROCESS.getName());
            detailVO.setOuterVerifySteps(baseMemberValidateService.getPlatformValidateOuterSteps(loginUser.getMemberRoleName()));
        } else {
            detailVO.setProcessName(MemberStringEnum.MEMBER_DEPOSIT_PROCESS.getName());
            detailVO.setOuterVerifySteps(baseMemberValidateService.getMemberDepositOuterSteps(relationDO));
        }

        detailVO.setCurrentOuterStep(relationDO.getVerified().equals(MemberValidateStatusEnum.VERIFY_PASSED.getCode()) ? 2 : 1);

        //详细信息分组内容
        detailVO.setGroups(baseMemberRegisterDetailService.groupMemberRegisterDetailText(relationDO.getSubMember()));

        //外部历史记录（即历史流转记录）
        detailVO.setOuterHistory(baseMemberHistoryService.listMemberOuterHistory(relationDO));

        return Wrapper.success(detailVO);
    }

    /**
     * App - 会员基本信息
     * @param relationDO 会员关系
     * @return 查询结果
     */
    @Override
    public Wrapper<MobileInfoBasicDetailVO> getMobileMemberBasicDetail(MemberRelationDO relationDO) {
        MemberDO subMember = relationDO.getSubMember();
        if (subMember == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        //查询所有平台关系，用于判断是否可以显示“修改注册资料”按钮
        List<MemberRelationDO> relationList = relationRepository.findBySubMemberIdAndRelType(relationDO.getSubMemberId(), MemberRelationTypeEnum.PLATFORM.getCode());

        MobileInfoBasicDetailVO detailVO = new MobileInfoBasicDetailVO();
        //是否可以修改注册资料（如果有其中一个正在平台审核，则不能修改)
        detailVO.setShowModify(relationList.stream().allMatch(r -> r.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode()) || r.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED.getCode())));
        //当前会员信息
        detailVO.setLogo(relationDO.getSubMember().getLogo());
        detailVO.setName(relationDO.getSubMember().getName());
        //会员基本信息
        detailVO.setOuterStatus(relationDO.getOuterStatus());
        detailVO.setOuterStatusName(MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()));
        detailVO.setAccount(relationDO.getSubMember().getAccount());
        detailVO.setPhone(relationDO.getSubMember().getPhone());
        detailVO.setEmail(relationDO.getSubMember().getEmail());
        detailVO.setCreateTime(relationDO.getCreateTime().format(ServiceConfig.DEFAULT_DATETIME_FORMATTER));
        Integer memberLevelTypeEnum = relationDO.getSubMemberLevelTypeEnum();
        detailVO.setMemberLevelTypeEnum(memberLevelTypeEnum);
        //渠道信息
        if (memberLevelTypeEnum.equals(MemberLevelTypeEnum.CHANNEL.getCode()) && relationDO.getChannel() != null) {
            detailVO.setChannelLevelTag(relationDO.getChannel() == null ? "" : relationDO.getChannel().getChannelLevelTag());
            detailVO.setChannelTypeName(relationDO.getChannel() == null ? "" : MemberChannelTypeEnum.getMsg(relationDO.getChannel().getChannelType().getChannelTypeEnum()));
            detailVO.setAreas(relationDO.getChannel() == null ? new ArrayList<>() : AgentAreaUtil.transferToList(relationDO.getChannel().getAgentArea()));
            detailVO.setRemark(relationDO.getChannel() == null ? "" : relationDO.getChannel().getRemark());
        } else {
            detailVO.setChannelLevelTag("");
            detailVO.setChannelTypeName("");
            detailVO.setAreas(new ArrayList<>());
            detailVO.setRemark("");
        }

        //详细信息分组内容
        detailVO.setGroups(baseMemberRegisterDetailService.groupMemberRegisterDetail(subMember, MemberDetailVersionEnum.USING));

        return Wrapper.success(detailVO);
    }

    /**
     * 会员详情 - 会员档案信息（入库信息）
     *
     * @param loginUser  登录用户
     * @param validateId 会员关系Id
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoDepositDetailVO> getMemberArchives(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MemberInfoDepositDetailVO detailVO = new MemberInfoDepositDetailVO();
        detailVO.setDepositDetails(baseMemberDepositDetailService.switchMemberDepositoryDetailText(relationDO));
        detailVO.setQualities(baseMemberQualificationService.findMemberQualities(relationDO));
        return Wrapper.success(detailVO);
    }

    /**
     * 会员详情- 会员档案 - 分页查询考评信息
     *
     * @param loginUser 登录用户
     * @param pageVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberAppraisalPageQueryVO>> pageMemberAppraisal(UserLoginCacheDTO loginUser, ValidateIdPageVO pageVO) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }
        return memberAppraisalService.pageMemberAppraisal(relationDO.getMember(), relationDO.getRole(), relationDO.getSubMember(), relationDO.getSubRole(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员档案 - 分页查询整改信息
     *
     * @param loginUser 登录用户
     * @param pageVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberRecordRectifyVO>> pageMemberRecordRectify(UserLoginCacheDTO loginUser, ValidateIdPageVO pageVO) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return memberRectifyService.pageMemberRecordRectify(relationDO.getMember(), relationDO.getRole(), relationDO.getSubMember(), relationDO.getSubRole(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员等级信息
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberValidateDetailLevelVO> getMemberDetailLevel(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailLevel(relationDO);
    }

    /**
     * 会员详情 - 会员等级信息 - 分页查询交易分获取记录
     * @param loginUser 登录用户
     * @param pageVO 接口参数
     * @param formatter 日期时间格式
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberDetailLevelHistoryVO>> pageMemberLevelDetailHistory(UserLoginCacheDTO loginUser, ValidateIdPageVO pageVO, DateTimeFormatter formatter) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberLevelDetailHistory(relationDO, pageVO.getCurrent(), pageVO.getPageSize(), formatter);
    }

    /**
     * 会员详情 - 会员等级信息 - 分页查询交易分获取记录
     *
     * @param relationDO 会员关系
     * @param current    当前页
     * @param pageSize   每页行数
     * @param formatter  日期时间格式
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberDetailLevelHistoryVO>> pageMemberLevelDetailHistory(MemberRelationDO relationDO, int current, int pageSize, DateTimeFormatter formatter) {
        return baseMemberDetailService.pageMemberLevelDetailHistory(relationDO, current, pageSize, formatter);
    }

    /**
     * 会员详情 - 会员权益信息
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberDetailRightVO> getMemberDetailRight(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailRight(relationDO);
    }

    /**
     * App - 会员信用 - 交易评价汇总
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MobileCommentSummaryVO> getMobileMemberDetailTradeCommentSummary(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MobileCommentSummaryVO summaryVO = new MobileCommentSummaryVO();

        CommentSummaryDTO summaryDTO = memberTradeCommentHistoryRepository.groupByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        if(summaryDTO != null && summaryDTO.getTotal() > 0) {
            int goodPercent = Math.round((float) summaryDTO.getGood() / summaryDTO.getTotal() * 100);
            int mediumPercent = Math.round((float) summaryDTO.getMedium() / summaryDTO.getTotal() * 100);
            int badPercent = Math.round((float) summaryDTO.getBad() / summaryDTO.getTotal() * 100);

            if(goodPercent + mediumPercent + badPercent != 100) {
                badPercent = 100 - goodPercent - mediumPercent;
            }

            summaryVO.setTotal(summaryDTO.getTotal());
            summaryVO.setGood(goodPercent);
            summaryVO.setMedium(mediumPercent);
            summaryVO.setBad(badPercent);
        }

        return Wrapper.success(summaryVO);
    }

    /**
     * 会员详情 - 会员权益信息 - 分页查询会员权益获取记录
     * @param loginUser 登录用户
     * @param pageVO 接口参数
     * @param formatter 日期时间格式
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberDetailRightHistoryVO>> pageMemberDetailRightHistory(UserLoginCacheDTO loginUser, ValidateIdPageVO pageVO, DateTimeFormatter formatter) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailRightHistory(relationDO, pageVO.getCurrent(), pageVO.getPageSize(), formatter);
    }

    /**
     * 会员详情 - 会员权益信息 - 分页查询会员权益使用记录
     * @param loginUser 登录用户
     * @param pageVO 接口参数
     * @param formatter 日期时间格式
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberDetailRightSpendHistoryVO>> pageMemberDetailRightSpendHistory(UserLoginCacheDTO loginUser, ValidateIdPageVO pageVO, DateTimeFormatter formatter) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailRightSpendHistory(relationDO, pageVO.getCurrent(), pageVO.getPageSize(), formatter);
    }

    /**
     * 会员详情 - 会员信用信息
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberDetailCreditVO> getMemberDetailCredit(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailCredit(relationDO);
    }

    /**
     * 会员详情 - 会员信用信息 - 交易评价汇总
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberDetailCreditCommentSummaryVO> getMemberDetailCreditTradeCommentSummary(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailCreditTradeCommentSummary(relationDO);
    }

    /**
     * 会员详情 - 会员信用 - 分页查询交易评论历史记录
     * @param loginUser 登录用户
     * @param pageVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberDetailCreditTradeHistoryVO>> pageMemberDetailCreditTradeCommentHistory(UserLoginCacheDTO loginUser, MemberDetailCreditHistoryPageVO pageVO) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailCreditTradeCommentHistory(relationDO, pageVO.getStarLevel(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员信用信息 - 售后评价汇总
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberDetailCreditCommentSummaryVO> getMemberDetailCreditAfterSaleCommentSummary(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.getMemberDetailCreditAfterSaleCommentSummary(relationDO);
    }

    /**
     * App - 会员信用 - 售后评价汇总
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MobileCommentSummaryVO> getMobileMemberDetailCreditAfterSaleCommentSummary(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MobileCommentSummaryVO summaryVO = new MobileCommentSummaryVO();

        CommentSummaryDTO summaryDTO = memberAfterSaleHistoryRepository.groupByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        if(summaryDTO != null && summaryDTO.getTotal() > 0) {
            int goodPercent = Math.round((float) summaryDTO.getGood() / summaryDTO.getTotal() * 100);
            int mediumPercent = Math.round((float) summaryDTO.getMedium() / summaryDTO.getTotal() * 100);
            int badPercent = Math.round((float) summaryDTO.getBad() / summaryDTO.getTotal() * 100);

            if(goodPercent + mediumPercent + badPercent != 100) {
                badPercent = 100 - goodPercent - mediumPercent;
            }

            summaryVO.setTotal(summaryDTO.getTotal());
            summaryVO.setGood(goodPercent);
            summaryVO.setMedium(mediumPercent);
            summaryVO.setBad(badPercent);
        }

        return Wrapper.success(summaryVO);
    }

    /**
     * 会员详情 - 会员信用 - 分页查询售后评论历史记录
     * @param loginUser 登录用户
     * @param pageVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberDetailCreditAfterSaleHistoryVO>> pageMemberDetailCreditAfterSaleCommentHistory(UserLoginCacheDTO loginUser, MemberDetailCreditHistoryPageVO pageVO) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return baseMemberDetailService.pageMemberDetailCreditAfterSaleCommentHistory(relationDO, pageVO.getStarLevel(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * 会员详情 - 会员信用 - 投诉汇总
     * @param loginUser 登录用户
     * @param validateId 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberDetailCreditComplainSummaryVO> getMemberDetailCreditComplainSummary(UserLoginCacheDTO loginUser, Long validateId) {
        MemberRelationDO relationDO = relationRepository.findById(validateId).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return memberComplaintService.summaryUpperMemberComplaints(relationDO.getMember(), relationDO.getRoleId(), relationDO.getSubMember(), relationDO.getSubRoleId());
    }

    /**
     * 会员详情 - 会员信用 - 分页查询投诉历史记录
     * @param loginUser 登录用户
     * @param pageVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberCreditComplaintPageQueryVO>> pageMemberDetailCreditComplainHistory(UserLoginCacheDTO loginUser, ValidateIdPageVO pageVO) {
        MemberRelationDO relationDO = relationRepository.findById(pageVO.getValidateId()).orElse(null);
        if (relationDO == null || !relationDO.getSubMemberId().equals(loginUser.getMemberId()) || !relationDO.getSubRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        return memberComplaintService.pageUpperMemberComplaint(relationDO.getMember(), relationDO.getRoleId(), relationDO.getSubMember(), relationDO.getSubRoleId(), pageVO.getCurrent(), pageVO.getPageSize());
    }

    /**
     * “增加会员角色”功能，查询上级会员列表
     *
     * @param subMemberId        下级会员id
     * @param subRoleId          下降会员角色id
     * @param enableMultiTenancy 是否开启sass多租户配置
     * @return 查询结果
     */
    @Override
    public Wrapper<UpperMemberShowVO> getUpperMemberInfo(Long subMemberId, Long subRoleId, Boolean enableMultiTenancy) {
        UpperMemberShowVO showVO = new UpperMemberShowVO();
        showVO.setShow(false);
        if (!enableMultiTenancy) {
            return Wrapper.success(showVO);
        }
        MemberRoleRuleDO roleRuleDO = roleRuleRepository.findByMemberId(subMemberId);

        //如果没有配置会员角色规则，则查找上级会员信息
        if (roleRuleDO == null) {
            //展示上级会员下拉框
            showVO.setShow(true);

            List<MemberRelationDO> relationDOList = relationRepository.findBySubMemberIdAndSubRoleIdAndSubMemberLevelTypeEnumNot(subMemberId, subRoleId, MemberLevelTypeEnum.PLATFORM.getCode());
            showVO.setUpperMemberList(relationDOList.stream().map(memberRelationDO -> new MemberManageVO(memberRelationDO.getMember().getId(), memberRelationDO.getMember().getName())).collect(Collectors.toList()));
            return Wrapper.success(showVO);
        }

        return Wrapper.success(showVO);
    }

    /**
     * “增加会员角色”功能，查询会员类型列表
     * @param memberTypeEnum 当前会员的会员类型
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberTypeIdAndNameVO>> getMemberTypeList(Integer memberTypeEnum) {
        //原企业会员增加会员角色，只能选择企业会员、渠道企业会员，原个人会员增加角色，只能选择个人会员、渠道个人会员
        //原渠道企业会员增加会员角色，只能选择渠道企业会员、企业会员，原渠道个人会员增加角色，只能选择渠道个人会员、个人会员
        List<MemberTypeIdAndNameVO> result;
        switch (MemberTypeEnum.toEnum(memberTypeEnum)) {
            case MERCHANT:
            case CHANNEL:
                result = memberTypeRepository.findByTypeEnumOrTypeEnum(MemberTypeEnum.MERCHANT.getCode(), MemberTypeEnum.CHANNEL.getCode(), Sort.by("id").ascending()).stream().map(memberTypeDO -> new MemberTypeIdAndNameVO(memberTypeDO.getId(), MemberTypeEnum.getCodeMessage(memberTypeDO.getTypeEnum()))).collect(Collectors.toList());
                break;
            case MERCHANT_PERSONAL:
            case CHANNEL_PERSONAL:
                result = memberTypeRepository.findByTypeEnumOrTypeEnum(MemberTypeEnum.MERCHANT_PERSONAL.getCode(), MemberTypeEnum.CHANNEL_PERSONAL.getCode(), Sort.by("id").ascending()).stream().map(memberTypeDO -> new MemberTypeIdAndNameVO(memberTypeDO.getId(), MemberTypeEnum.getCodeMessage(memberTypeDO.getTypeEnum()))).collect(Collectors.toList());
                break;
            default:
                result = new ArrayList<>();
                break;
        }

        return Wrapper.success(result);
    }

    /**
     * “增加会员角色”功能，查询会员适用类型列表（saas）
     *
     * @param memberTypeEnum   当前会员的会员类型
     * @param roleManageVOList 会员适用角色list
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberTypeIdAndNameVO>> getMemberTypeList(Integer memberTypeEnum, List<RoleRuleManageVO> roleManageVOList) {
        List<MemberTypeIdAndNameVO> result;
        switch (MemberTypeEnum.toEnum(memberTypeEnum)) {
            case MERCHANT:
            case CHANNEL:
                result = roleManageVOList.stream().filter(roleManageVO -> roleManageVO.getMemberTypeEnum().intValue() == MemberTypeEnum.MERCHANT.getCode() || roleManageVO.getMemberTypeEnum().intValue() == MemberTypeEnum.MERCHANT_PERSONAL.getCode())
                        .map(roleManageVO -> new MemberTypeIdAndNameVO(roleManageVO.getMemberTypeId(), roleManageVO.getMemberTypeName())).distinct().collect(Collectors.toList());
                break;
            case MERCHANT_PERSONAL:
            case CHANNEL_PERSONAL:
                result = roleManageVOList.stream().filter(roleManageVO -> roleManageVO.getMemberTypeEnum().intValue() == MemberTypeEnum.MERCHANT_PERSONAL.getCode() || roleManageVO.getMemberTypeEnum().intValue() == MemberTypeEnum.CHANNEL_PERSONAL.getCode())
                        .map(roleManageVO -> new MemberTypeIdAndNameVO(roleManageVO.getMemberTypeId(), roleManageVO.getMemberTypeName())).distinct().collect(Collectors.toList());
                break;
            default:
                result = new ArrayList<>();
                break;
        }
        return Wrapper.success(result);
    }

    /**
     * “增加会员角色”功能，根据会员类型Id查询角色列表，以及勾选的角色Id列表
     * @param subMemberId 下级会员Id
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoRoleListVO> getRoleListByMemberType(Long subMemberId, MemberTypeIdVO idVO) {
        MemberDO memberDO = memberRepository.findById(subMemberId).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        List<Long> roleIds = memberDO.getRoles().stream().map(RoleDO::getId).collect(Collectors.toList());
        MemberInfoRoleListVO listVO = new MemberInfoRoleListVO();
        listVO.setRoles(baseMemberValidateService.getRoleListByMemberType(idVO.getMemberTypeId()));
        listVO.setCheckIds(roleIds.stream().filter(roleId -> listVO.getRoles().stream().anyMatch(roleIdAndNameVO -> roleIdAndNameVO.getRoleId().equals(roleId))).collect(Collectors.toList()));
        return Wrapper.success(listVO);
    }

    /**
     * “增加会员角色”功能，根据会员类型Id查询角色列表(saas)
     *
     * @param memberId         会员id
     * @param idVO             接口参数
     * @param roleManageVOList 会员适用角色list
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoRoleListVO> getRoleListByMemberType(Long memberId, MemberTypeIdVO idVO, List<RoleRuleManageVO> roleManageVOList) {
        MemberDO memberDO = memberRepository.findById(memberId).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }
        List<Long> roleIds = memberDO.getRoles().stream().map(RoleDO::getId).collect(Collectors.toList());
        MemberInfoRoleListVO listVO = new MemberInfoRoleListVO();

        listVO.setRoles(roleManageVOList.stream().filter(roleManageVO -> roleManageVO.getMemberTypeId().equals(idVO.getMemberTypeId())).map(roleManageVO -> new RoleIdAndNameVO(roleManageVO.getRoleId(), roleManageVO.getRoleName())).collect(Collectors.toList()));
        listVO.setCheckIds(roleIds.stream().filter(roleId -> listVO.getRoles().stream().anyMatch(roleIdAndNameVO -> roleIdAndNameVO.getRoleId().equals(roleId))).collect(Collectors.toList()));
        return Wrapper.success(listVO);
    }

    /**
     * “增加会员角色”功能，会获取员注册资料信息
     * @param subMemberId 下级会员Id
     * @param subRoleId 下级会员角色Id
     * @param roleIdVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInfoUpdateDetailByRoleVO> getMemberRegisterDetailAfterAddRole(Long subMemberId, Long subRoleId, RoleIdVO roleIdVO) {
        MemberDO memberDO = memberRepository.findById(subMemberId).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        RoleDO loginUserRole = memberDO.getRoles().stream().filter(role -> role.getId().equals(subRoleId)).findFirst().orElse(null);
        if (loginUserRole == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        RoleDO roleDO = roleRepository.findById(roleIdVO.getRoleId()).orElse(null);
        if (roleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        //角色是否已经存在
        if (memberDO.getRoles().stream().anyMatch(r -> r.getId().equals(roleIdVO.getRoleId()))) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_EXISTS);
        }

        //判断角色是否错误
        Wrapper<Void> checkResult = baseMemberValidateService.checkRoleWithMemberType(roleDO, loginUserRole.getMemberType().getTypeEnum());
        if (checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        MemberInfoUpdateDetailByRoleVO detailVO = new MemberInfoUpdateDetailByRoleVO();
        detailVO.setOuterVerifySteps(baseMemberValidateService.getPlatformValidateOuterSteps(roleDO.getRoleName()));
        detailVO.setCurrentOuterStep(1);

        //基本信息
        detailVO.setMemberId(memberDO.getId());

        //合并会员原来的，与角色的注册信息
        detailVO.setGroups(baseMemberRegisterDetailService.mergeMemberRegisterDetail(memberDO, MemberDetailVersionEnum.USING, roleDO));

        //外部历史记录（即历史流转记录）
        detailVO.setOuterHistory(new ArrayList<>());
        return Wrapper.success(detailVO);
    }

    /**
     * “增加会员角色”功能，提交注册资料并新增角色
     * @param subMemberId 下级会员Id
     * @param subRoleId 下级会员角色Id
     * @param addRoleVO 接口参数
     * @return 新增结果
     */
    @Override
    public Wrapper<Void> addMemberRole(Long subMemberId, Long subRoleId, MemberInfoAddRoleVO addRoleVO) {
        MemberDO memberDO = memberRepository.findById(subMemberId).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        RoleDO loginUserRole = memberDO.getRoles().stream().filter(role -> role.getId().equals(subRoleId)).findFirst().orElse(null);
        if (loginUserRole == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        //不需要判断是否有未通过审核的角色
        RoleDO roleDO = roleRepository.findById(addRoleVO.getRoleId()).orElse(null);
        if (roleDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        Wrapper<Void> roleCheck = baseMemberValidateService.checkRoleWithMemberType(roleDO, loginUserRole.getMemberType().getTypeEnum());
        if (roleCheck.getCode() != ResponseCode.SUCCESS.getCode()) {
            return roleCheck;
        }

        //角色是否已经存在
        if (memberDO.getRoles().stream().anyMatch(r -> r.getId().equals(addRoleVO.getRoleId()))) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_EXISTS);
        }

        //会员管理员和管理员角色
        if (CollectionUtils.isEmpty(memberDO.getMemberRoles())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_ROLE_DOES_NOT_EXIST);
        }

        MemberRoleDO memberAdminRole = memberDO.getMemberRoles().stream().filter(memberRoleDO -> memberRoleDO.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())).findFirst().orElse(null);
        if (memberAdminRole == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_ROLE_DOES_NOT_EXIST);
        }

        if (CollectionUtils.isEmpty(memberDO.getUsers())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        MemberUserDO memberAdminUser = memberDO.getUsers().stream().filter(memberUserDO -> memberUserDO.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())).findFirst().orElse(null);
        if (memberAdminUser == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        //平台管理员和角色
        MemberDO adminMemberDO = memberRepository.findFirstByAccount(ServiceConfig.PLATFORM_SUPER_ADMIN_ACCOUNT);
        if (adminMemberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        if (CollectionUtils.isEmpty(adminMemberDO.getRoles())) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        RoleDO adminRole = adminMemberDO.getRoles().iterator().next();
        if (adminRole == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_DOES_NOT_EXIST);
        }

        //从现有的注册资料进行检查
        Set<MemberConfigDO> memberConfigSet = memberDO.getRegisterDetails().stream().map(MemberRegisterDetailDO::getMemberConfig).collect(Collectors.toSet());
        memberConfigSet.addAll(roleDO.getConfigs());

        List<MemberRegisterDetailDO> registerDetails = new ArrayList<>();
        Wrapper<String> checkResult = baseMemberRegisterDetailService.checkMemberRegisterDetail(addRoleVO.getDetail(), new ArrayList<>(memberConfigSet), registerDetails, memberDO.getName());
        if (checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        //公司名称是否已被注册
        String memberName = checkResult.getData();
        if (StringUtils.hasLength(memberName) && memberRepository.existsByNameAndIdNot(memberName, subMemberId)) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_NAME_REGISTERED);
        }

        //查询角色的平台审核流程配置
        Wrapper<ProcessBO> processResult = basePlatformProcessService.findRolePlatformProcess(roleDO);
        if(processResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(processResult.getCode(), processResult.getMessage());
        }

        return memberInnerService.addMemberRole(processResult.getData(), loginUserRole.getRoleName(), adminMemberDO, adminRole, memberDO, roleDO, memberAdminRole, memberAdminUser, memberName, registerDetails);
    }
}
